home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 June: Reference Library / Dev.CD Jun 96 RL / Dev.CD Jun 96 RL.toast / Technical Documentation / develop / develop Issue 23 / develop Issue 23 code / ProjectDrag 1.1b8 / Sources / ProjectDrag Sources / SourceServer.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-07  |  8.9 KB  |  334 lines  |  [TEXT/MPS ]

  1. /* SourceServer.c: How to create and send an AppleEvent to SourceServer for ProjectDrag.
  2.  *
  3.  * A set of applets for drag and drop source control by Tim Maroney.
  4.  * See develop, issue 23 for details.
  5.  *
  6.  * Built on DropShell by Leonard Rosenthol, Stephan Somogyi, and Marshall Clow,
  7.  * and using the MoreFiles utilities by Jim Luther.
  8.  *
  9.  * This software is free, but don't modify and redistribute it without
  10.  * changing the status window to indicate your name and your changes!
  11.  */
  12.  
  13. #include <Errors.h>
  14. #include <Finder.h>
  15. #include <Strings.h>
  16. #include <string.h>
  17.  
  18. #include "SourceServer.h"
  19. #include "MoreFiles.h"
  20. #include "MoreFilesExtras.h"
  21. #include "DSUtils.h"
  22. #include "SignatureToApp.h"
  23. #include "ProjectAlias.h"
  24. #include "PDDialogs.h"
  25. #include "PDUtilities.h"
  26. #include "TasksAndErrors.h"
  27.  
  28.  
  29. #define kSSCommandID 'cmnd'
  30.  
  31.  
  32.  
  33. /* send an Apple event to SourceServer. See develop 23 for details */
  34.  
  35. OSErr SourceServerCommand(AEDesc *command, CStringHandle *output, CStringHandle *diagnostic,
  36.                             AEIdleUPP idleProc, AEFilterUPP filterProc)
  37. {
  38.     AppleEvent aeEvent, aeReply;
  39.     AEDesc sourceServerAddress;
  40.     ProcessSerialNumber sourceServerProcess;
  41.     FSSpec appSpec; /* SignatureToApp requires this, documentation to the contrary.... */
  42.     long theLong, theSize;
  43.     DescType theType;
  44.     AEDesc paramDesc;
  45.     OSErr err;
  46.  
  47.     /* default replies */
  48.     *output = NULL;
  49.     *diagnostic = NULL;
  50.     
  51.     /* find the SourceServer */
  52.     TaskStart(kProjectDragStrings, kFindingSourceServer, NULL, NULL, NULL, NULL);
  53.     err = SignatureToApp(kSourceServerCreator, NULL, &sourceServerProcess, &appSpec, NULL,
  54.                           Sig2App_LaunchApplication, launchContinue + launchDontSwitch);
  55.     if (err != noErr) return err;
  56.     err = AECreateDesc(typeProcessSerialNumber, (Ptr) &sourceServerProcess, sizeof(ProcessSerialNumber),
  57.                          &sourceServerAddress);
  58.     if (err != noErr) return err;
  59.     TaskDone();
  60.  
  61.     /* Create the SourceServer Apple Event */
  62.     err = AECreateAppleEvent(kSourceServerType, kSSCommandID, &sourceServerAddress, kAutoGenerateReturnID,kAnyTransactionID, 
  63.                                &aeEvent);
  64.     AEDisposeDesc(&sourceServerAddress);
  65.     if (err != noErr) return err;
  66.  
  67.     /* add the command descriptor to the event */
  68.     err = AEPutParamDesc(&aeEvent, keyDirectObject, command);
  69.     if (err != noErr) { AEDisposeDesc(&aeEvent); return err; }
  70.     
  71.     /* send the apple event */
  72.     err = AESend(&aeEvent, &aeReply, kAEWaitReply + kAENeverInteract, kAENormalPriority,
  73.                  kNoTimeOut, idleProc, filterProc);
  74.     AEDisposeDesc(&aeEvent);
  75.     if (err != noErr) return err;
  76.  
  77.     /* check for an error return */
  78.     err = AEGetParamPtr(&aeReply, keyErrorNumber, typeInteger, &theType, &theLong,
  79.                         sizeof(long), &theSize);
  80.     if (err != noErr || (err = theLong) != noErr)
  81.         return err;
  82.  
  83.     /* get the command output */
  84.     err = AEGetParamDesc (&aeReply, keyDirectObject, typeChar, ¶mDesc);
  85.     if (err == noErr)
  86.         *output = (CStringHandle)paramDesc.dataHandle;
  87.     
  88.     /* get the diagnostic output */
  89.     err = AEGetParamDesc (&aeReply, 'diag', typeChar, ¶mDesc);
  90.     if (err == noErr)
  91.         *diagnostic = (CStringHandle)paramDesc.dataHandle;
  92.     
  93.     /* get the MPW status -- it becomes our error return */
  94.     err = AEGetParamPtr(&aeReply, 'stat', typeInteger, &theType, &theLong,
  95.                         sizeof(long), &theSize);
  96.     if (err == noErr)
  97.         err = theLong;
  98.  
  99.     AEDisposeDesc(&aeReply);
  100.  
  101.     return err;
  102. }
  103.  
  104.  
  105. OSErr CreateCommand(AEDesc *command, CString commandText)
  106. {
  107.     OSErr err = AECreateList(NULL, 0 , false, command);
  108.     if (err == noErr)
  109.     {
  110.         err = AddCStringArg(command, commandText);
  111.         if (err != noErr) AEDisposeDesc(command);
  112.     }
  113.     if (err != noErr)
  114.     {
  115.         /* this makes it safe to dispose the descriptor */
  116.         command->descriptorType = typeNull;
  117.         command->dataHandle = NULL;
  118.     }
  119.     return err;
  120. }
  121.  
  122.  
  123. OSErr AddCommentArg(AEDesc *command, StringPtr comment)
  124. {
  125.     OSErr err;
  126.     if (comment[0] == 0) return noErr;
  127.     err = AddCStringArg(command, "-cs");
  128.     if (err != noErr) return err;
  129.     err = AddPStringArg(command, comment);
  130.     return err;
  131. }
  132.  
  133.  
  134. OSErr AddDirArg(AEDesc *command, short vRefNum, long folderID)
  135. {
  136.     FSSpec dirSpec;
  137.     OSErr err = AddCStringArg(command, "-d");
  138.     if (err != noErr) return err;
  139.     dirSpec.vRefNum = vRefNum;
  140.     dirSpec.parID = folderID;
  141.     dirSpec.name[0] = 0;
  142.     err = AddFileNameArg(command, &dirSpec);
  143.     return err;
  144. }
  145.  
  146.  
  147. OSErr AddProjectArg(AEDesc *command, StringPtr projectName)
  148. {
  149.     OSErr err = AddCStringArg(command, "-project");
  150.     if (err != noErr) return err;
  151.     err = AddPStringArg(command, projectName);
  152.     return err;
  153. }
  154.  
  155.  
  156. OSErr AddUserArg(AEDesc *command, StringPtr userName)
  157. {
  158.     OSErr err = AddCStringArg(command, "-u");
  159.     if (err != noErr) return err;
  160.     err = AddPStringArg(command, userName);
  161.     return err;
  162. }
  163.  
  164.  
  165. OSErr AddFileNameArg(AEDesc *command, FSSpec *file)
  166. {
  167.     Str255 fileName;
  168.     OSErr err = MakeFullPathName(file, fileName);
  169.     if (err != noErr) return err;
  170.     err = AddPStringArg(command, fileName);
  171.     return err;
  172. }
  173.  
  174.  
  175. OSErr AddPStringArg(AEDesc *command, StringPtr string)
  176. {
  177.     OSErr err;
  178.     p2cstr(string);
  179.     err = AEPutPtr(command, 0, typeChar, string, strlen(string) + 1);
  180.     c2pstr(string);
  181.     return err;
  182. }
  183.  
  184.  
  185. OSErr AddCStringArg(AEDesc *command, CString string)
  186. {
  187.     OSErr err = AEPutPtr(command, 0, typeChar, string, strlen(string) + 1);
  188.     return err;
  189. }
  190.  
  191.  
  192. /* utility routines with task and error notification built in */
  193.  
  194.  
  195. OSErr SendCommand(AEDesc *command)
  196. {
  197.     OSErr err;
  198.     CStringHandle output = NULL, diagnostic = NULL;
  199.     
  200.     err = SourceServerCommand(command, &output, &diagnostic, ProjectDragIdleProc, NULL);
  201.     if (err != noErr || diagnostic != NULL)
  202.     {
  203.         if (err == noErr) err = -1;
  204.         if (diagnostic != NULL)
  205.             ResTextDisplayDialog(kProjectDragStrings, kProjectorError, diagnostic);
  206.         else
  207.             RaiseErrorNumber(err);
  208.     }
  209.     else if (output != NULL)
  210.         ResTextDisplayDialog(kProjectDragStrings, kProjectorOutput, output);
  211.     if (output != NULL)
  212.         DisposeHandle((Handle)output);
  213.     if (diagnostic != NULL)
  214.         DisposeHandle((Handle)diagnostic);
  215.     AEDisposeDesc(command);
  216.     return err;
  217. }
  218.  
  219.  
  220. OSErr MountProject(AliasHandle projectAlias)
  221. {
  222.     OSErr err;
  223.     CStringHandle output = NULL, diagnostic = NULL;
  224.     
  225.     err = MountProjectAlias(projectAlias, &output, &diagnostic);
  226.     if (err != noErr || diagnostic != NULL)
  227.     {
  228.         if (err == noErr) err = -1;
  229.         if (diagnostic != NULL)
  230.             ResTextDisplayDialog(kProjectDragStrings, kCantFindProject, diagnostic);
  231.         else
  232.             RaiseErrorNumber(err);
  233.     }
  234.     if (output != NULL)
  235.         DisposeHandle((Handle)output);
  236.     if (diagnostic != NULL)
  237.         DisposeHandle((Handle)diagnostic);
  238.     DisposeHandle((Handle)projectAlias);
  239.     return err;
  240. }
  241.  
  242.  
  243. OSErr MountProjectFromFolder(short vRefNum, long folderID, StringPtr projectName)
  244. {
  245.     AliasHandle projectAlias;
  246.     OSErr err;
  247.     
  248.     TaskStart(kProjectDragStrings, kFindingProject, NULL, NULL, NULL, NULL);
  249.     err = FindProjectAliasFromFolder(vRefNum, folderID, &projectAlias, projectName);
  250.     if (err != noErr)
  251.     {
  252.         /* couldn't find it -- ask the user for one */
  253.         FSSpec file;
  254.         if (SelectProjectorDB(&file, kProjectDragStrings, kCantFindProjectCanYou, NULL, NULL))
  255.         {
  256.             Str31 folderName;
  257.             
  258.             /* get the name of the parent of ProjectorDB -- it's the project name */
  259.             err = GetDirName(file.vRefNum, file.parID, projectName);
  260.             if (err != noErr) return RaiseErrorNumber(err);
  261.             
  262.             /* get the name of the parent of the checkout folder */
  263.             err = GetDirName(vRefNum, folderID, folderName);
  264.             if (err != noErr) return RaiseErrorNumber(err);
  265.             
  266.             /* if the name of the checkout folder is different from the project name,
  267.              * we need to create a mapping between them
  268.              */
  269.             if (!EqualString(folderName, projectName, false, false))
  270.             {
  271.                 err = AddNameMapping(folderName, projectName);
  272.                 if (err != noErr) return RaiseErrorNumber(err);
  273.             }
  274.  
  275.             /* user picked a ProjectorDB -- now make an alias for it */
  276.             err = MakeProjectAlias(file.vRefNum, file.parID, &projectAlias);
  277.             if (err != noErr) return RaiseErrorNumber(err);
  278.         }
  279.         else
  280.         {
  281.             /* user canceled the standard file dialog */
  282.             return RaiseErrorNumber(userCanceledErr);
  283.         }
  284.     }
  285.     TaskDone();
  286.     return MountProject(projectAlias);
  287. }
  288.  
  289.  
  290. /* filter ProjectorDB files based on project name -- must be the same as in the CKID */
  291.  
  292. pascal Boolean FindProjectFileFilter(CInfoPBPtr pb, Ptr myDataPtr)
  293. {
  294.     StringPtr projectName = myDataPtr;
  295.     Str63 folderName;
  296.     OSErr err;
  297.     
  298.     /* get the name of the parent folder */
  299.     err = GetDirName(pb->hFileInfo.ioVRefNum, pb->hFileInfo.ioFlParID, folderName);
  300.     if (err != noErr) return true; /* error means suppress */
  301.     
  302.     /* compare them */
  303.     return !EqualString(projectName, folderName, false, false);
  304. }
  305.  
  306.  
  307. OSErr MountProjectFromCKID(CKIDHandle theCKID, StringPtr projectName)
  308. {
  309.     AliasHandle projectAlias;
  310.     OSErr err;
  311.     
  312.     TaskStart(kProjectDragStrings, kFindingProject, NULL, NULL, NULL, NULL);
  313.     err = FindProjectAliasFromCKID(theCKID, &projectAlias, projectName);
  314.     if (err != noErr) 
  315.     {
  316.         FSSpec file;
  317.         Str31 topProjectName;
  318.         
  319.         GetTopProjectName(projectName, topProjectName);
  320.         if (SelectProjectorDB(&file, kProjectDragStrings, kCantFindProjectCanYou,
  321.                                 FindProjectFileFilter, topProjectName))
  322.         {
  323.             err = MakeProjectAlias(file.vRefNum, file.parID, &projectAlias);
  324.             if (err != noErr) return RaiseErrorNumber(err);
  325.         }
  326.         else
  327.         {
  328.             return RaiseErrorNumber(userCanceledErr);
  329.         }
  330.     }
  331.     TaskDone();
  332.     return MountProject(projectAlias);
  333. }
  334.